/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * EcranRetouche.java
 *
 * Created on 8 avr. 2010, 09:04:16
 */

package vue;

import controleur.CCLogger;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Vector;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputAdapter;
import main.Outils;
import modele.*;
import vue.composants.EcranRetoucheImage;

/**
 *
 * @author Synapse
 */
public class EcranRetouche extends Ecran {

    // Panel central de dessin de l'image avec effet
    private EcranRetoucheImage eri;

    // L'image source à modifier
    private Image image;

    // La zone de destination
    private ZoneImage zone;

    // Informations sur les effets appliqués
    private boolean noirEtBlanc;
    private boolean sepia;
    private int rotation;
    private int luminosite;
    private int contraste;
    private Rectangle selection;

    // Les effets
    public enum Effet {NOIRBLANC, SEPIA, ROTATION, LUMINOSITE, CONSTRASTE};

    // Effet en cours d'utilisation
    private Effet effetEnCours;

    // Pas pour les modifications
    private final int ROTATION_PAS = 5;
    private final int LUMINOSITE_PAS = 5;
    private final int CONTRASTE_PAS = 5;

    // Indique si le slider est en train de bouger ou non
    private boolean slidding;

    /**
     * Constructeur de la class EcranRetouche
     * @param mere de type FenetreMere
     * @see FenetreMere
     */
    public EcranRetouche(FenetreMere mere) {
        super(mere);

        initComponents();

        try
        {
            initialiser();

            Dimension tailleImageCentrale = new Dimension(650, 650);
            eri = new EcranRetoucheImage(this, tailleImageCentrale);

            panelImage.setLayout(new BorderLayout());
            panelImage.add(eri, BorderLayout.CENTER);
        }
        catch (Exception ex) {
            CCLogger.Write(Level.SEVERE, Outils.getStackTrace(ex));
            this.afficherMessageErreur("Une erreur est survenue lors de l'initialison de l'écran Retouche.");
        }

    }


    /**
     * Initialisation de l'écran.
     */
    public void initialiser() {

        // L'image source à modifier
        image = ressources.getImageSurZone().getImage();
        zone = ressources.getImageSurZone().getZone();

        // Par défaut aucun effet
        noirEtBlanc = false;
        sepia = false;
        rotation = 0;
        luminosite = 0;
        contraste = 0;
        selection = null;

        // Pas de slidding
        slidding = false;

        // Aucun effet en cours d'utilisation
        effetEnCours = Effet.ROTATION;
        quitterModeEffet();
    }


    /**
     * Permet au controleur de récupérer l'image après validation
     *
     * @return L'image avec les effets appliqués
     */
    public Image getImageAvecEffets() {
        Image imageAvecEffet = null;

        try
        {
            // On récupère la BufferedImage
            BufferedImage bufferedImage = eri.getImageAvecEffet();

            // On créer une Image avec
            imageAvecEffet = new Image(null, null, null, bufferedImage);
        }
        catch (Exception ex) {
            CCLogger.Write(Level.SEVERE, ex.getStackTrace().toString());
            this.afficherMessageErreur(ex.getMessage());
        }

        // On la retourne
        return imageAvecEffet;
    }


    /**
     * Entrer en mode effet
     * @param effet
     */
    private void entrerModeEffet(Effet effet) {

        effetEnCours = effet;

        if(effetEnCours == Effet.ROTATION) {
            btnGauche.setText("-");
            btnDroite.setText("+");
            labInformation.setText("Rotation : " + rotation + "°");
            btnLuminosite.setSelected(false);
            btnContraste.setSelected(false);
            btnRotation.setSelected(true);

            int conversion = (int)Math.round( (double)rotation / (double)1.8 );
            slider.setValue(conversion);
            slider.setMinimum(-100);
            slider.setMaximum(100);
            slider.setVisible(true);
            
        }
        else if(effetEnCours == Effet.LUMINOSITE) {
            btnGauche.setText("-");
            btnDroite.setText("+");
            labInformation.setText("Luminosité : " + luminosite + "%");
            btnRotation.setSelected(false);
            btnContraste.setSelected(false);
            btnLuminosite.setSelected(true);
            slider.setValue(luminosite);
            slider.setMinimum(-100);
            slider.setMaximum(100);
            slider.setVisible(true);
            
        }
        else if(effetEnCours == Effet.CONSTRASTE) {
            btnGauche.setText("-");
            btnDroite.setText("+");
            labInformation.setText("Contraste : " + contraste + "%");
            btnRotation.setSelected(false);
            btnLuminosite.setSelected(false);
            btnContraste.setSelected(true);
            slider.setValue(contraste);
            slider.setMinimum(-100);
            slider.setMaximum(100);
            slider.setVisible(true);
            
        }

//        btnGauche.setVisible(true);
//        btnDroite.setVisible(true);
          btnGauche.setEnabled(true);
          btnDroite.setEnabled(true);
    }


    /**
     * Modifier la valeur d'un effet.
     * @param effet
     * @param valeur
     */
    private void modifierValeurEffet(boolean positif) {

        if(effetEnCours == Effet.ROTATION) {
            rotation += ROTATION_PAS * (positif ? 1 : -1);
            rotation %= 360;
            labInformation.setText("Rotation : " + rotation + "°");

            int conversion = (int)Math.round( (double)rotation / (double)1.8 );
            slider.setValue(conversion);
        }
        else if(effetEnCours == Effet.LUMINOSITE) {
            luminosite += LUMINOSITE_PAS * (positif ? 1 : -1);
            luminosite %= 100;
            labInformation.setText("Luminosité : " + luminosite + "%");
            slider.setValue(luminosite);
        }
        else if(effetEnCours == Effet.CONSTRASTE) {
            contraste += CONTRASTE_PAS * (positif ? 1 : -1);
            contraste %= 100;
            labInformation.setText("Contraste : " + contraste + "%");
            slider.setValue(contraste);
        }

        redessinerImage();
    }


    /**
     * Modifier la valeur d'un effet par le slider
     * @param effet
     * @param valeur
     */
    private void modifierValeurEffetParSlider(int valeur) {

        if(effetEnCours == Effet.ROTATION) {
            int conversion = (int)Math.round( (double)valeur * (double)1.8 );
            rotation = conversion;
//            rotation %= 360;
            labInformation.setText("Rotation : " + rotation + "°");
        }
        else if(effetEnCours == Effet.LUMINOSITE) {
            luminosite = valeur;
//            luminosite %= 100;
            labInformation.setText("Luminosité : " + luminosite + "%");
        }
        else if(effetEnCours == Effet.CONSTRASTE) {
            contraste = valeur;
//            contraste %= 100;
            labInformation.setText("Contraste : " + contraste + "%");
        }

        redessinerImage();
    }


    /**
     * Entrer en mode effet
     * @param effet
     */
    private void quitterModeEffet() {

        // Aucun effet en cours, rien à faire
        if( effetEnCours == null )
            return;

        effetEnCours = null;

//        btnGauche.setVisible(false);
//        btnDroite.setVisible(false);
        btnGauche.setEnabled(false);
        btnDroite.setEnabled(false);
        labInformation.setText(" ");
        slider.setVisible(false);

        btnRotation.setSelected(false);
        btnContraste.setSelected(false);
        btnLuminosite.setSelected(false);

    }


    private void basculerNoirEtBlanc() {
        noirEtBlanc = btnNoirEtBlanc.isSelected();
        sepia = false;
        btnSepia.setSelected(false);
        redessinerImage();
    }

    private void basculerSepia() {
        sepia = btnSepia.isSelected();
        noirEtBlanc = false;
        btnNoirEtBlanc.setSelected(false);
        redessinerImage();
    }

    /**
     * Redessine l'image avec tous les paramètres des effets.
     */
    public void redessinerImage() {
        repaint();
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        panelBoutonsHaut = new javax.swing.JPanel();
        btnNoirEtBlanc = new javax.swing.JToggleButton();
        btnSepia = new javax.swing.JToggleButton();
        btnContraste = new javax.swing.JToggleButton();
        btnLuminosite = new javax.swing.JToggleButton();
        btnRotation = new javax.swing.JToggleButton();
        panelBoutonsBas = new javax.swing.JPanel();
        btnAnnuler = new javax.swing.JButton();
        btnValider = new javax.swing.JButton();
        labInformation = new javax.swing.JLabel();
        panelBoutonsGauche = new javax.swing.JPanel();
        btnGauche = new javax.swing.JButton();
        panelBoutonsDroite = new javax.swing.JPanel();
        btnDroite = new javax.swing.JButton();
        panelImage = new javax.swing.JPanel();

        panelBoutonsBasCentre = new javax.swing.JPanel();
        slider = new javax.swing.JSlider();

        Vector<Component> boutons = new Vector<Component>();
        boutons.add(btnNoirEtBlanc);
        boutons.add(btnSepia);
        boutons.add(btnContraste);
        boutons.add(btnLuminosite);
        boutons.add(btnRotation);
        boutons.add(btnAnnuler);
        boutons.add(btnValider);

        setBackground(new java.awt.Color(255, 255, 255));
        setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 204, 255), 2));
        setMaximumSize(new java.awt.Dimension(1024, 768));
        setMinimumSize(new java.awt.Dimension(1024, 768));

        btnNoirEtBlanc.setText("Noir et blanc");
        btnSepia.setText("Sépia");
        btnContraste.setText("Contraste");
        btnLuminosite.setText("Luminosité");
        btnRotation.setText("Rotations");
        btnAnnuler.setText("Annuler");
        btnValider.setText("Valider");

        labInformation.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        labInformation.setText("< Informations >");
        labInformation.setFont(new java.awt.Font("Tahoma", 0, 18));

        btnGauche.setText("-");
        btnDroite.setText("+");

        slider.setSize(400, 40);
        slider.setVisible(false);

        for (Component bouton : boutons) {
            bouton.setSize(140,50);
            bouton.setFont(new java.awt.Font("Tahoma", 0, 18));
        }
        btnDroite.setSize(50,50);
        btnDroite.setFont(new java.awt.Font("Tahoma", 0, 18));
        btnGauche.setSize(50,50);
        btnGauche.setFont(new java.awt.Font("Tahoma", 0, 18));


        panelBoutonsHaut.setLayout(new FlowLayout());
        panelBoutonsHaut.add(btnNoirEtBlanc);
        panelBoutonsHaut.add(btnSepia);
        panelBoutonsHaut.add(btnRotation);
        panelBoutonsHaut.add(btnLuminosite);
        panelBoutonsHaut.add(btnContraste);

        panelBoutonsBasCentre.setLayout( new GridLayout(1, 2) );
        panelBoutonsBasCentre.add(labInformation);
        panelBoutonsBasCentre.add(slider);

        panelBoutonsBas.setLayout(new BorderLayout());
        panelBoutonsBas.add(btnAnnuler, BorderLayout.WEST);
        panelBoutonsBas.add(panelBoutonsBasCentre, BorderLayout.CENTER);
        panelBoutonsBas.add(btnValider, BorderLayout.EAST);

        panelBoutonsGauche.setLayout(new FlowLayout());
        panelBoutonsGauche.add(btnGauche);

        panelBoutonsDroite.setLayout(new FlowLayout());
        panelBoutonsDroite.add(btnDroite);

        setLayout(new BorderLayout());
        add(panelBoutonsHaut, BorderLayout.NORTH);
        add(panelBoutonsGauche, BorderLayout.WEST);
        add(panelBoutonsDroite, BorderLayout.EAST);
        add(panelBoutonsBas, BorderLayout.SOUTH);
        add(panelImage, BorderLayout.CENTER);


        btnNoirEtBlanc.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                basculerNoirEtBlanc();
            }
        });

        btnSepia.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                basculerSepia();
            }
        });

        btnRotation.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(effetEnCours != Effet.ROTATION)
                    entrerModeEffet(Effet.ROTATION);
                else
                    quitterModeEffet();
            }
        });

        btnLuminosite.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(effetEnCours != Effet.LUMINOSITE)
                    entrerModeEffet(Effet.LUMINOSITE);
                else
                    quitterModeEffet();
            }
        });

        btnContraste.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(effetEnCours != Effet.CONSTRASTE)
                    entrerModeEffet(Effet.CONSTRASTE);
                else
                    quitterModeEffet();
            }
        });

        btnGauche.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                modifierValeurEffet(false);
            }
        });

        btnDroite.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                modifierValeurEffet(true);
            }
        });

        slider.addChangeListener( new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                if(effetEnCours != null)
                    modifierValeurEffetParSlider(slider.getValue());
            }
        });
        
        btnAnnuler.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                controleur.trEffetAnnuler();
            }
        });

        btnValider.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                controleur.trEffetValider();
            }
        });

        // On place un listener sur le slider, cela permettra de savoir si l'on
        // est en train de glisser/déposer le slider.
        MouseInputAdapter sliderListener = new MouseInputAdapter() {
            public void mousePressed(MouseEvent e) {
                slidding = true;
            }
            public void mouseReleased(MouseEvent e) {
                slidding = false;
            }
        };
        slider.addMouseListener(sliderListener);
    }
    /**
     * Getter pour le contraste
     * @return int, veleur de contraste
     */
    public int getContraste() {
        return contraste;
    }

    /**
     * Setter pour le contraste
     * @param contraste int, valeur du constraste a mettre
     */
    public void setContraste(int contraste) {
        this.contraste = contraste;
    }

    /**
     * Getter pour l'image
     * @return Image
     */
    public Image getImage() {
        return image;
    }

    /**
     * Setter pour l'image
     * @param image
     */
    public void setImage(Image image) {
        this.image = image;
    }

    /**
     * Getter pour la zone image
     * @return ZoneImage
     */
    public ZoneImage getZone() {
        return zone;
    }

    /**
     * Setter pour la zone image
     * @param zone ZoneImage, la zone pour l'image
     */
    public void setZone(ZoneImage zone) {
        this.zone = zone;
    }

    /**
     * Getter pour la luminosité
     * @return int, valeur de la luminosité
     */
    public int getLuminosite() {
        return luminosite;
    }

    /**
     * Setter pour la luuminosité
     * @param luminosite int, valeur de la luminosité
     */
    public void setLuminosite(int luminosite) {
        this.luminosite = luminosite;
    }

    /**
     * Permet de savoir si l'image est en Noir et Blanc
     * @return boolean, true si l'image est en Noir et Blanc
     */
    public boolean isNoirEtBlanc() {
        return noirEtBlanc;
    }

    /**
     * Setter pour mettre à jour le flag du Noir et Blanc
     * @param noirEtBlanc boolean, permet de mettre à jour le flag pour le Noir et Blanc
     */
    public void setNoirEtBlanc(boolean noirEtBlanc) {
        this.noirEtBlanc = noirEtBlanc;
    }

    /**
     * Getter pour la rotation
     * @return int, valeur de la rotation
     */
    public int getRotation() {
        return rotation;
    }

    /**
     * Setter pour la rotation
     * @param rotation int, valeur de la rotation
     */
    public void setRotation(int rotation) {
        this.rotation = rotation;
    }

    /**
     * Permet de savoir si l'image est en Sépia
     * @return boolean, true si l'image est en Sépia
     */
    public boolean isSepia() {
        return sepia;
    }

    /**
     * Setter pour mettre à jour le flag du Sépia
     * @param sepia boolean, permet de mettre à jour le flag pour le Sépia
     */
    public void setSepia(boolean sepia) {
        this.sepia = sepia;
    }

    /**
     * Permet de savoir si l'image est slidding
     * @return boolean
     */
    public boolean isSlidding() {
        return slidding;
    }


    // Variables declaration - do not modify
    private javax.swing.JButton btnAnnuler;
    private javax.swing.JToggleButton btnContraste;
    private javax.swing.JButton btnDroite;
    private javax.swing.JButton btnGauche;
    private javax.swing.JToggleButton btnLuminosite;
    private javax.swing.JToggleButton btnNoirEtBlanc;
    private javax.swing.JToggleButton btnRotation;
    private javax.swing.JToggleButton btnSepia;
    private javax.swing.JButton btnValider;
    private javax.swing.JLabel labInformation;
    private javax.swing.JPanel panelBoutonsBas;
    private javax.swing.JPanel panelBoutonsBasCentre;
    private javax.swing.JPanel panelBoutonsDroite;
    private javax.swing.JPanel panelBoutonsGauche;
    private javax.swing.JPanel panelBoutonsHaut;
    private javax.swing.JPanel panelImage;
    private javax.swing.JSlider slider;
    // End of variables declaration

}
